package com.dscyy.readutil;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 
 * 生产 课程访问 清单
 * 
 * @author dscyy
 *
 */
public class ReadTxtByKecheng {
	
	static Map<Integer, HourLimitPercentage> limtHourMap = null;
	static Map<Integer, HourLimitPercentage> limtMonthMap = null;
	
	static String fileSort = "1";
	static int useUserQty = 75;
	
//	static String[] fileSortarg = {"1", "2", "3", "4", "5"};
//	static int[] useUserQtyarg = {45, 76, 100, 49, 105};
	static String[] fileSortarg = {"26"};
	static int[] useUserQtyarg = {298};
	static String firstStartDate = "2018-09-01";
	static int randomDate = 30;
	

	public static void main(String[] args) throws Exception {
		int a = 1;
		if(a == 2) {
			System.out.println(calcStartDate());
		}else {
			List<String> allSql = new ArrayList<String>();
			for(int i = 0; i < fileSortarg.length; i++) {
				fileSort = fileSortarg[i];
				useUserQty = useUserQtyarg[i];
				List<String[]> allUser = readUser();// 全部用户
				List<String[]> allCurs = readCurs();// 全部课程
				Map<String, String> cursMap = new HashMap<String, String>();
				for(String[] cur : allCurs) {
					cursMap.put(cur[1], cur[2]);
				}
				List<String[]> readLimitHour = readLimitHour();// 时间限制
				limtHourMap = new HashMap<Integer, HourLimitPercentage>();
				for(String[] lh : readLimitHour) {
					HourLimitPercentage p = new HourLimitPercentage();
					p.setHour(Integer.parseInt(lh[1]));
					p.setLimitPerc(Double.parseDouble(lh[2]));
					p.setNums(0);
					p.setNowperc(0);
					limtHourMap.put(p.getHour(), p);
				}
				List<String[]> readLimitMonth = readLimitMonth();// 时间限制
				limtMonthMap = new HashMap<Integer, HourLimitPercentage>();
				for(String[] lh : readLimitMonth) {
					HourLimitPercentage p = new HourLimitPercentage();
					p.setHour(Integer.parseInt(lh[1]));
					p.setLimitPerc(Double.parseDouble(lh[2]));
					p.setNums(0);
					p.setNowperc(0);
					limtMonthMap.put(p.getHour(), p);
				}
				
				// 得到指定数量的用户
				List<String> fuser = filterNumsUser(allUser, useUserQty,  0); 
				String sql = "";
				for(String u : fuser) {
					// 得到随机数量的课程
					List<String> fcurs = filterNumsUser(allCurs, Integer.parseInt(Math.round(Math.random()*allCurs.size())+""), 1); 
	//				String startDate = calcStartDate();
					String startDate = calcStartDateFromApril();
					// 上课课程分段
					List<String[]> curses = new ArrayList<String[]>();
					splitCursToSomeList(fcurs, curses);
					// 给每次上课加个时间
					List<String[]> cuswithTime = addTimeToEveryCurs(curses, startDate);
					for(String[] ct : cuswithTime) {
	//					System.out.println(u + "           " + ct[0] + "           " + ct[1]);
						int lgtime = cursMap.get(ct[0]).equals("0") ? Integer.parseInt(Math.round(Math.random()*100)+""):Integer.parseInt(Math.round(Math.random()*Integer.parseInt(cursMap.get(ct[0])))+"");
						sql = "insert into wp_vd_visters(cursid,userid,visttime,lgtime) values("+ct[0]+",'"+u+"',STR_TO_DATE('"+ct[1]+"','%Y-%m-%d %H:%i:%s'),"+lgtime+");";
						allSql.add(sql);
					}
				}
			}
			writeSqlToFile(allSql, "d:\\Desktop\\initdata\\201809Vistors.sql");
		}
		
	}
	
	private static void writeSqlToFile(List<String> allSql, String fileName) {
		try {
			FileWriter writer = new FileWriter(fileName);
			for(String sql : allSql) {
				writer.write(sql + "\n");
			}
			writer.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 给每次上课加个时间
	 * @param curses
	 * @param startDate
	 * @throws ParseException 
	 */
	private static List<String[]> addTimeToEveryCurs(List<String[]> curses, String startDate) throws ParseException {
		List<String[]> cuswithTime = new ArrayList<String[]>();
		SimpleDateFormat f=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		// 得到随机的 时分秒
//		int hour =  Integer.parseInt(Math.round(Math.random()*24)+"");
//		int minus =  Integer.parseInt(Math.round(Math.random()*60)+"");
//		int seconds =  Integer.parseInt(Math.round(Math.random()*60)+"");
//		startDate = startDate + " " + addPreZerobyCount(hour, 2) + ":" + addPreZerobyCount(minus, 2) + ":"  + addPreZerobyCount(seconds, 2);
		startDate = startDate + " 00:00:00";
		Calendar c = Calendar.getInstance();
		c.setTime(f.parse(startDate));
		for(String[] oneLevelCus : curses) {
			int hour = Integer.parseInt(Math.round(Math.random()*24)+""); 
			hour = limitHourPercentage(1, hour);
			c.set(Calendar.HOUR_OF_DAY, hour);
			c.add(Calendar.MINUTE, Integer.parseInt(Math.round(Math.random()*60)+""));
			c.add(Calendar.SECOND, Integer.parseInt(Math.round(Math.random()*60)+""));
			for(String cur : oneLevelCus) {
				String[] custime = new String[2];
				custime[0] = cur;
				custime[1] = f.format(c.getTime());
				cuswithTime.add(custime);
				int addMinute =  Integer.parseInt(Math.round(Math.random()*15)+"");
				c.add(Calendar.MINUTE, addMinute);
				// 校验hour 是否超标
				hour = limitHourPercentage(1, c.get(Calendar.HOUR_OF_DAY));
				c.set(Calendar.HOUR_OF_DAY, hour);
			}
			c.add(Calendar.DAY_OF_YEAR, Integer.parseInt(Math.round(Math.random()*10)+""));
		}
		return cuswithTime;
	}

	/**
	 * 限制每个小时出现的百分比
	 * @return
	 */
	private static int limitHourPercentage(int limitinvoke, int hour) {
		limitinvoke++;
		if(hour == 24) {
			hour = 0;
		}
		if(limitinvoke > 25 || isInLimitHour(hour)) {
			return hour;
		}else {
			hour++;
			return limitHourPercentage(limitinvoke, hour);
		}
	}
	
	private static int limitMonthPercentage(int limitinvoke, int month) {
		limitinvoke++;
		if(limitinvoke > 3 || isInLimitMonth(month)) {
			return month;
		}else {
			if(month==4)
				month = 5;
			else if(month==5)
				month = 6;
			else
				month = 4;
			return limitHourPercentage(limitinvoke, month);
		}
	}

	private static boolean isInLimitHour(int hour) {
		HourLimitPercentage cur = limtHourMap.get(hour);
		if(cur.getNowperc() <= cur.getLimitPerc()) {
			cur.setNums(cur.getNums()+1);
			updateLimitMaps();
			return true;
		}else {
			return false;
		}
		
	}
	
	private static boolean isInLimitMonth(int hour) {
		HourLimitPercentage cur = limtMonthMap.get(hour);
		if(cur.getNowperc() <= cur.getLimitPerc()) {
			cur.setNums(cur.getNums()+1);
			updateMonthLimitMaps();
			return true;
		}else {
			return false;
		}
		
	}

	private static void updateLimitMaps() {
		if(limtHourMap.containsKey(100)) { // 记录包括总数的key
			HourLimitPercentage totHLP = limtHourMap.get(100);
			totHLP.setNums(totHLP.getNums()+1);
			// 遍历map，重算百分比
			for (HourLimitPercentage value : limtHourMap.values()) {
				if(value.getHour() != 100) {
					value.setNowperc(value.getNums()*1.0/totHLP.getNums()*100.00);
				}
			}
		}else { // // 记录不包括总数的key，计算出来一个
			calcTotalKeyValue();
			updateLimitMaps();
		}
		
	}
	
	private static void updateMonthLimitMaps() {
		if(limtMonthMap.containsKey(100)) { // 记录包括总数的key
			HourLimitPercentage totHLP = limtMonthMap.get(100);
			totHLP.setNums(totHLP.getNums()+1);
			// 遍历map，重算百分比
			for (HourLimitPercentage value : limtMonthMap.values()) {
				if(value.getHour() != 100) {
					value.setNowperc(value.getNums()*1.0/totHLP.getNums()*100.00);
				}
			}
		}else { // // 记录不包括总数的key，计算出来一个
			calcMonthTotalKeyValue();
			updateMonthLimitMaps();
		}
		
	}

	private static void calcTotalKeyValue() {
		int total = 0;
		for (HourLimitPercentage value : limtHourMap.values()) {
			total += value.getNums();
		}
		HourLimitPercentage totHLP = new HourLimitPercentage();
		totHLP.setNums(total);
		totHLP.setHour(100);
		limtHourMap.put(100, totHLP);
	}
	
	private static void calcMonthTotalKeyValue() {
		int total = 0;
		for (HourLimitPercentage value : limtMonthMap.values()) {
			total += value.getNums();
		}
		HourLimitPercentage totHLP = new HourLimitPercentage();
		totHLP.setNums(total);
		totHLP.setHour(100);
		limtMonthMap.put(100, totHLP);
	}

	private static String addPreZerobyCount(int seconds, int count) {
		if(String.valueOf(seconds).length()>=count) {
			return String.valueOf(seconds);
		}else {
			String pre = "";
			for(int i = 0; i < count-String.valueOf(seconds).length(); i++) {
				pre += "0";
			}
			return pre + String.valueOf(seconds);
		}
		
	}

	private static void splitCursToSomeList(List<String> fcurs, List<String[]> curses) {
		if(fcurs != null && fcurs.size() < 6) {
			String[] onecurs = new String[fcurs.size()];
			moveInArrayString(onecurs, fcurs, fcurs.size());
			curses.add(onecurs);
		}else if(fcurs != null && fcurs.size() > 0){
			int count = Integer.parseInt(Math.round(Math.random() * fcurs.size())+"");
			String[] onecurs = new String[count];
			moveInArrayString(onecurs, fcurs, count);
			curses.add(onecurs);
			
			if(fcurs != null && fcurs.size() > 0)
				splitCursToSomeList(fcurs,  curses);
			
		}
	}

	private static void moveInArrayString(String[] onecurs, List<String> fcurs, int count) {
		Iterator<String> it = fcurs.iterator();
		int index = 0;
		while(it.hasNext() && count-- > 0) {
			onecurs[index++] = it.next();
			it.remove();
		}
	}

	private static String calcStartDate() throws ParseException {
		int mon = Integer.parseInt(Math.round(Math.random() * 12)+"");
		String year = "2017";
		String month = "";
		if(mon <= 6) {
			year = "2018";
			month = "0" + String.valueOf(mon);
		}else {
			year = "2017";
			if(mon>=10)
				month = String.valueOf(mon);
			else
				month = "0" + String.valueOf(mon);
				
		}
		SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
		Date date = f.parse(year + "-" + month + "-01");
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.DAY_OF_YEAR, Integer.parseInt(Math.round(Math.random() * 20)+""));
		if(mon == 6 || c.getTime().compareTo(new Date()) >= 0) {
			return calcStartDate();
		}
		return f.format(c.getTime());
	}
	
	private static String calcStartDateFromApril() throws ParseException {
		SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
		Date date = f.parse(firstStartDate);
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.DAY_OF_YEAR, Integer.parseInt(Math.round(Math.random() * randomDate)+""));
		
		return f.format(c.getTime());
	}

	public static List<String> filterNumsUser(List<String[]> allUser, int nums, int index){
		List<String> users = new ArrayList<String>();
		// 将用户列表整理成map
		Map<Integer, String[]> map = new HashMap<Integer, String[]>();
		int key = 1;
		for(String[] str : allUser) {
			map.put(key++, str);
		}
		// 随机取数
		int allCount = map.size();
		if(nums == 0) {
			nums = allCount;
		}
		for(int i=1;i <= nums; i++) {
			queryUserInMap(users, map, allCount, index);
		}
		return users;
	}
	
	private static void queryUserInMap(List<String> users, Map<Integer, String[]> map, int allCount, int index) {
		String strKey = Math.round(Math.random() * allCount)+"";
		Integer key = Integer.parseInt((strKey));
		if(map.containsKey(key)) {
			users.add(map.get(key)[index]);
			map.remove(key);
		}else {
			queryUserInMap(users, map, allCount, index);
		}
		
	}

	private static List<String[]> readUser() throws Exception{
		// 读取用户数据
		String filename = "d:\\Desktop\\initdata\\downnames"+fileSort+".txt";
		String regex = "	";
		return readFiles(filename, regex);
	}
	
	private static List<String[]> readCurs() throws Exception{
		// 读取用户数据
		String filename = "d:\\Desktop\\initdata\\wp_vd_visters"+fileSort+".csv";
		String regex = ",";
		return readFiles(filename, regex);
	}	
	
	private static List<String[]> readLimitHour() throws Exception{
		// 读取用户数据
		String filename = "d:\\Desktop\\initdata\\limithour.csv";
		String regex = ",";
		return readFiles(filename, regex);
	}	
	
	private static List<String[]> readLimitMonth() throws Exception{
		// 读取用户数据
		String filename = "d:\\Desktop\\initdata\\limitmonth.csv";
		String regex = ",";
		return readFiles(filename, regex);
	}	

	private static List<String[]> readFiles(String filename, String regex) throws Exception {
		List<String[]> lineList = new ArrayList<String[]>();
		FileReader fr = new FileReader(filename);

		int ch = 0;
		String line = "";
		while ((ch = fr.read()) != -1) {
			if(ch != 13)
				line+=(char) ch;
			else {
				lineList.add(line.replaceAll("\n", "").split(regex));
				line = "";
			}
		}
		fr.close();
		return lineList;
	}


}
